package com.lsh.oms.core.proxy.handler;

import com.lsh.oms.core.redis.RedisTemplate;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.text.MessageFormat;
import java.util.concurrent.TimeUnit;

/**
 * Project Name: lsh-oms
 * @author: panxudong
 * 北京链商电子商务有限公司
 * Desc: 类功能描述
 * Package Name: com.lsh.oms.provider.service.business
 * Time: 2017-08-21 上午10:49
 */
@Service
@Lazy(false)
public class OrderConcurrentHandler {

    private static final Logger logger = LoggerFactory.getLogger(OrderConcurrentHandler.class);

    private static final String LOCK_TEMPLATE = "oms:order:concurrent:lock:{0}";
    private static final String ORDER_CANCEL_LOCK = "oms:order:cancel:lock:{0}";
    private static final Long LOCK_EXPIRED_TIME = 300L;
    private static final String LOCK = "lock";
    private static RedisTemplate redisTemplate;

    @Autowired
    private RedisTemplate redisTemplateTemp;

    public static boolean lockOrder(Long orderCode) {
        String redisKey = loadRedisKey(orderCode);
        logger.info("Order concurrent handler, lock " + orderCode + " start");
        boolean isSuccess = redisTemplate.lock(redisKey, 60);
        logger.info("Order concurrent handler, lock " + orderCode + " " + isSuccess);
        return isSuccess;
    }

    public static boolean unlockOrder(Long orderCode) {
        String redisKey = loadRedisKey(orderCode);
        logger.info("Order concurrent handler, unlock " + orderCode + " start");
        boolean isSuccess = redisTemplate.unlock(redisKey);
        logger.info("Order concurrent handler, unlock " + orderCode + " " + isSuccess);
        return isSuccess;
    }

    public static boolean setExpiredLock(Long orderCode) {
        String key = getOrderCancelMarkKey(orderCode);
        logger.info("Order cancel mark lock! orderCode: {}", orderCode);
        boolean isSuccess = redisTemplate.set(key, LOCK, false, LOCK_EXPIRED_TIME, TimeUnit.SECONDS) != null;
        logger.info("Order cancel mark lock! orderCode: {}", orderCode);
        return isSuccess;
    }

    public static boolean isExists(Long orderCode) {
        String key = getOrderCancelMarkKey(orderCode);
        return redisTemplate.exists(key);
    }

    private static String loadRedisKey(Long orderCode) {
        return MessageFormat.format(LOCK_TEMPLATE, String.valueOf(orderCode));
    }

    private static String getOrderCancelMarkKey(Long orderCode) {
        return MessageFormat.format(ORDER_CANCEL_LOCK, String.valueOf(orderCode));
    }

    @PostConstruct
    public void init() {
        redisTemplate = redisTemplateTemp;
    }
}
